02. Instructions
Project Rubric
Your project will be evaluated by a Udacity code reviewer according to the Memory Game project rubric. Please review for detailed project requirements.
Get the Starter Code
If you'd like to start from scratch without any files, you are encouraged to do so! You learn the most by developing on your own! But, it can be a bit challenging having to start from scratch, so we do provide a starter project (i.e., a "skeleton") to use.
You can download this starter code through either:
The starter code has a static, non-interactive version of the project so you can get a jump-start on development!
JavaScript and the DOM
Great! You now have the starter code. Before moving forward, make sure you are comfortable with the content from JavaScript and the DOM. Ask yourself:
- What is the Document?
- What are events?
- How do we listen for them?
- How does event delegation help us avoid too many events?
- Check Working with Browser Events in JavaScript and the DOM for a refresher if needed
- How can we access elements with the following two methods? What are the differences between them?
- How do you use getElementbyId() to select a DOM element by its
id? - We can also access elements with getElementsByClassName(). What does this method return, and how do you use it?
- How do you use the className property? What does it return, and why would it be useful?
- What are the different methods for classList?
- Hint: the
add(),remove(), andtoggle()methods look particularly useful…
- Hint: the
- Every element has an innerHTML property that represents the markup of the element's content. How can you leverage this property to get and set content?
Development Strategy
For this project, you will be writing most of your code in js/app.js. Note that it's very important that you plan your project before you start writing any code! Break your project down into small pieces of work and strategize your approach to each one. With these bite-sized amounts, it'll be easier to debug and fix any issues that appear.
Feel free to implement your own design workflow, but if you get stuck -- here is a walkthrough to get you up and running!
Start by building a grid of cards. The rest of your game's functionality depends on this grid.
- How many total pairs of cards would you have?
- Take a quick look at all the HTML elements in index.html. Note the values for their
classattributes. To manipulate the DOM, you'll be using many of the tools and methods you've learned on these elements (and on those that you will create) - Which data structure can you use to store these individual cards? This data structure can represent your entire list of cards, so it might be a good idea to save it to a variable
- How you would iterate (i.e., loop) over this data structure?
- Think about how you can create, say, an unordered list (i.e., bulleted list) in HTML from this structure
- Are your cards randomly placed onto the grid? Note that the provided
shuffle()function (from the starter code) takes in anarrayparameter, and returns a shuffled version of that array - Figure out the HTML needed to represent a card. Remember, you have to represent two sides of the card, and the symbols are faced down
- How can you use CSS properties like
transformoropacityto represent the sides of a card?
Add the functionality to handle clicks. This should reveal the "hidden" side of each card. Clicking on the first card should turn it over, show the symbol, and remain turned over. Clicking on a different card must also turn it over and show the symbol.
- Which event are you listening for (hint: you were just reading it)?
- How can that event affect CSS? Hint: Look at the static page (index.html) provided in the starter code. Pay special attention to the
classvalues on open/shown cards, matched cards, and the rest of the cards (i.e., those without their symbols shown). WhichclassListmethods can you use to change the value of an element'sclassupon that event happening? - Recall what you know about event delegation. Rather than adding an event listener to each individual card (which can be a costly operation), is there a way to add just one to a common parent node? Take a closer look at index.html to see which node that could be
- Toggling cards will happen pretty often in this game. To keep your code clean and DRY, consider refactoring this operation into its own function
Work on the matching logic. At this point, your users can flip over cards on the grid! Now the question is: how does your game "know" if a player guesses correctly or incorrectly?
- Think about how you can temporarily store opened cards. After all, one card turned over needs to be compared to another card turned over. Which data structure would be great to temporarily hold these turned-over cards? Make sure this data structure doesn't hold too many cards! We're only looking for a match between two cards; it wouldn't make sense to store and compare, say, three cards at the same time
- How can you prevent the user from selecting the same card twice?
- When comparing two different cards for a match, what exactly can you compare? (hint: open up index.html and look at the child of each
<li>element) - If the two cards match, they stay turned over
- How does a match affect the
classof these cards? (hint: check theclassvalues of the two matched cards in the static index.html file from the starter code)
- How does a match affect the
- If the two cards do not match, they turn back
- How does this affect the data structure that temporarily stored these cards?
- All this logic to match cards seems like it'll be used quite often. Consider refactoring the code for checking for a match into its own function
Create the winning condition. How does your game “know” if a player has won?
- Your user should see a modal when the game ends
- What information can this modal show? See below!
Implement additional functionality:
- Move counter. The game should display the number of moves the player has made
- Hint: Declaring a variable with an initial value
0is a good start - How can you use
innerHTMLto actually display that value?
- Hint: Declaring a variable with an initial value
- Timer. This timer should start when the player starts a game, and end when the player wins the game
- Hint: How can
setTimeout()come into play here?
- Hint: How can
- Star rating. The player should begin with a certain number of stars displayed on the screen. The number of moves made during the game should visually decrease this star rating
- Hint: You'll probably want to build this only after you've build the move counter
- Reset button. This should allow the player to reset the entire grid as well as all the above
- Move counter. The game should display the number of moves the player has made
- We recommend saving most of the styling until the very end. Allow your game logic and functionality to dictate the styling.
Version Control
Although not a requirement, we recommend using Git from the very beginning. Make sure to commit often and to use well-formatted commit messages that conform to our Git Style Guide.
Udacity Style Guides
You should write your code and markup to meet the specifications provided in these style guides:
Still Not Sure How to Begin?
To reiterate, be sure that you are comfortable with the content from JavaScript and the DOM. After all, this entire project is about DOM manipulation! You are also welcome to review this post in Knowledge, which includes several student-curated resources for this particular project.
Beyond that, feel free to check out Mike's webinar on the Memory Game project below!
FEND P3 - Memory Game With Mike Wales
INSTRUCTOR NOTE:
For another perspective on the project, check out Ryan's webinar as well.
A note on plagiarism: Viewing someone else’s code to get a general idea of implementation, then putting it away and starting to write your own code from scratch is okay. Please do not copy someone's code, in whole or in part. For further details, check out this guide regarding plagiarism.